home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part1 / 8903 < prev    next >
Encoding:
Text File  |  1996-08-05  |  3.5 KB  |  92 lines

  1. Path: apccorp.apcc.com!root
  2. From: nfegan@apcc.com (Noel Fegan)
  3. Newsgroups: comp.lang.c++
  4. Subject: Re: polymorphism and style
  5. Date: Tue, 27 Feb 1996 09:55:33 GMT
  6. Organization: American Power Conversion
  7. Message-ID: <4gukfu$amc@apccorp.apcc.com>
  8. References: <4gr4ur$n13@alpha.pcix.com>
  9. NNTP-Posting-Host: hewie.galway.apcc.com
  10. X-Newsreader: Forte Free Agent 1.0.82
  11.  
  12. ed lizewski <elizewsk@capecod.net> wrote:
  13.  
  14. >  Question on polymorphism and style.
  15. >Want to call a function in a most derived class off a pointer to the base
  16. >class. The fuction does not exist in the base class.
  17. >I should:
  18. >1)downcast ?
  19. >2)add the function to the base class and add virtual stubs to every 
  20. >  class that does not use it ? 
  21. >3)add it to the base class but define it like 
  22. >     foo( ..whatever..) {error_msg("virtual function not defined");}
  23. >  This way only the class that uses it would have to define it.
  24. >4) ?
  25. >thanks for your time.
  26.  
  27. If you add a virtual stub function in the base class for every virtual function
  28. in the derived class, or derived classes, then you are adding unnecessary
  29. complexity to the base class. On top of that, sometimes the source of the base
  30. classes we interact with are not ours to add to, or it is not wise to mess with
  31. them, take MFC for example. 
  32.  
  33. In most cases, it is OK to cast the base pointer to the derived type, but you
  34. must be sure that you are doing a valid cast. The compiler can tell you that a
  35. cast is invalid only in the case that you are casting a base class pointer to an
  36. unrelated type. Once the cast is to a valid derived class the compiler accepts
  37. that you know what you are doing, even though the actual object may have been
  38. constructed as something else.
  39.  
  40. There are precautions you can take to safe guard against this type of situation
  41. arising. If you create an object of a derived type, then you should refer to it
  42. through its actual class type as much as possible.
  43.  
  44. For example, say we have a class called Window which forms the base class for a
  45. windowing class library.
  46.  
  47. //simplified Window class
  48. class Window {
  49.   private:
  50.     Window * m_parent;
  51.   public:
  52.                                Window (Window * parent) : m_parent(parent) { }
  53.     virtual Window * GetParent (void) { return(m_parent); }
  54.   };
  55.  
  56. From this class we derive class like ControlWindow, EditControl, ...
  57.  
  58. //simplified ControlWindow class
  59. class ControlWindow : public Window {
  60.   public:
  61.     ControlWindow (Window * parent) : Window(parent) { }
  62.   };
  63.  
  64. class EditControl : public ControlWindow {
  65.   public:
  66.     EditControl (ControlWindow * parent, /*other args*/) : ControlWindow(parent)
  67. { ...}
  68.   };
  69.  
  70. When we construct an EditControl object we do it as follows:
  71.  
  72. EditControl * pEdit = new EditControl(this, /* other args */);
  73.  
  74. If we then want to pass a pointer to this object to a function which
  75. specifically requires an EditControl (or some derived class of EditControl), we
  76. do not make the pointer argument to the function be anything less than
  77. EditControl. If you make the function argument Window then you are leaving
  78. youself open to misuse and you cannot be sure that any casting you do in the
  79. function. The constructor for EditControl takes a pointer to a ControlWindow (a
  80. type derived form Window) ) as the type of its parent. If the function mentioned
  81. above calls GetParent() , a base class virtual function which returns a Window
  82. *, we know that we can safely cast this to ControlWindow because we have kept
  83. good control over our pointer types.
  84.  
  85. If you look at the MFC source code you will see quite a lot of casting of this
  86. type, if its OK for MFC, it's OK for me.
  87. --
  88. Noel Fegan
  89. American Power Conversion
  90.  
  91.